package ink.teamwork.battery.config;


import ink.teamwork.battery.service.RedisService;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

@Configuration
@Order(-1)
public class FilterConfig implements Filter {

    private final static String BEARER = "Bearer ";

    private final RedisService redisService;

    public FilterConfig(RedisService redisService) {
        this.redisService = redisService;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
        if (HttpMethod.OPTIONS.name().equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }
        decide(request, response, filterChain);
    }

    public void decide(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String uri = request.getRequestURI();
        String authorization = request.getHeader("Authorization");
        if (uri.contains("/oauth/token")
            || uri.contains("/system/login")
            || uri.contains("/login")
            || uri.contains("/course/callback")
            || uri.startsWith("/css")
            || uri.startsWith("/js")
            || uri.startsWith("/v3/api-docs")
            || uri.startsWith("/swagger-ui")
        ) {
            chain.doFilter(request, response);
            return;
        }

        if (!uri.startsWith("/api") && !uri.startsWith("/app")) {
            chain.doFilter(request, response);
            return;
        }

        String accessToken = null;
        if (authorization != null && authorization.contains(BEARER)) {
            accessToken = authorization.split(" ")[1];
        }
        if (accessToken == null) {
            accessToken = request.getParameter("accessToken");
        }

        if (accessToken == null) {
            writeToJson(response, 401, "未知的ACCESS_TOKEN");
            return;
        }
        request.setAttribute("accessToken", accessToken);
        chain.doFilter(request, response);
    }

    public void writeToJson(HttpServletResponse response, int code, String msg) {
        response.setStatus(code);
        response.setContentType("application/json; charset=utf-8");
        response.setCharacterEncoding("UTF-8");
        try {
            OutputStream out = response.getOutputStream();
            out.write(String.format("{\"code\": %d, \"msg\": \"%s\"}", code, msg).getBytes(StandardCharsets.UTF_8));
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

